<template>
  <view class="pages-container" :style="[containerStyle]">
    <Loading
      :loading="pageLoading"
      :type="loadingType"
      :text="loadingText"
      :text-style="loadingTextStyle"
      :context-style="loadingContextStyle"
      :is-full="scrollContainer"
    >
      <scroll-view
        v-if="scrollContainer"
        scroll-y
        class="scroll-container"
        :style="[scrollStyle]"
        scroll-anchoring
        :refresher-enabled="scrollRefresher"
        :refresher-triggered="scrollState.refreshStatus"
        @refresherrefresh="refresherRefresh"
        @scrolltolower="scrollToLower"
        @scrolltoupper="scrollToUpper"
      >
        <slot></slot>
      </scroll-view>
      <slot v-else></slot>
    </Loading>
    <!--  todo: 扩展出顶部提示  -->
  </view>
</template>

<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator'
import Loading from '@/components/loading/loading.vue'
import { sleep } from '@/utils/helper/uniHelper'
import {
  getMenuButtonBoundingRect,
  getSystemSetting
} from '@/utils/helper/cacheQueryHelper'

@Component({ name: 'PagesContainer', components: { Loading } })
export default class PagesContainer extends Vue {
  // 配合自定义导航栏使用
  @Prop({ type: Boolean, default: false }) hasCustomNavbar!: boolean
  // 开启 loading 动画
  @Prop({ type: Boolean, default: false }) loading!: boolean
  @Prop({ type: Number, default: 1 }) loadingType!: number
  @Prop({ type: String, default: null }) loadingText!: string
  @Prop({ type: Object, default: () => ({}) }) loadingTextStyle!: Recordable
  @Prop({ type: Object, default: () => ({}) }) loadingContextStyle!: Recordable
  // 启用滚动容器
  @Prop({ type: Boolean, default: false }) scrollContainer!: boolean
  @Prop({ type: Object, default: () => ({}) }) scrollStyle!: Recordable
  // 启用下拉刷新
  @Prop({ type: Boolean, default: false }) scrollRefresher!: boolean
  @Prop({ type: Boolean, default: false }) scrollToUpperAllow!: boolean
  @Prop({ type: Boolean, default: false }) scrollToLowerAllow!: boolean
  @Prop({ type: Object, default: () => ({}) })
  scrollLoadMoreOptions!: Recordable

  get pageLoading() {
    return this.loading
  }

  containerStyle: Recordable = {
    Height: '100vh'
  }

  created() {
    if (this.hasCustomNavbar) {
      const { statusBarHeight = 24 } = getSystemSetting()
      const { top, bottom } = getMenuButtonBoundingRect()
      // this.containerStyle = {
      //   height: `calc(100vh - ${top - statusBarHeight + bottom}px)`
      // }
    }
  }

  scrollState = {
    // 当前下拉刷新状态
    refreshStatus: false,
    // 是否正在操作
    isHandle: false
  }

  refresherRefresh() {
    if (this.scrollState.isHandle) return
    this.scrollState.isHandle = true
    this.scrollState.refreshStatus = true

    this.$emit('onRefresh', async () => {
      await sleep(300)
      this.scrollState.refreshStatus = false
      this.scrollState.isHandle = false
    })
  }

  scrollToUpper() {
    if (!this.scrollToUpperAllow) return
    if (this.scrollState.isHandle) return
    this.scrollState.isHandle = true

    this.$emit('scrollToUpper', async () => {
      await sleep(300)
      this.scrollState.isHandle = false
    })
  }

  scrollToLower() {
    if (!this.scrollToLowerAllow) return
    if (this.scrollState.isHandle) return
    this.scrollState.isHandle = true

    this.$emit('scrollToLower', async () => {
      await sleep(300)
      this.scrollState.isHandle = false
    })
  }
}
</script>

<style lang="scss">
.pages-container {
  width: 100vw;
  position: relative;
  padding: 0;
}

.scroll-container {
  box-sizing: border-box;
  height: 100%;
}
</style>
